/**
 * Project:   dtu.fmes.googleloon
 * File:      SimulationExecutor.java
 * License: 
 *            This file is licensed under GNU General Public License version 3
 *            http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * Copyright: Bartosz Cichecki [ cichecki.bartosz@gmail.com ]
 * Date:      Oct 5, 2013
 */

package dtu.fmes.loon.simulation;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;

import dtu.fmes.loon.simulation.processors.SimulationLink;
import dtu.fmes.loon.singletons.CurrentSimulationStateSingleton;
import dtu.fmes.loon.singletons.SimulationStateHistorySingleton;

/**
 * 
 * @author Bartosz Cichecki
 */
public class SimulationExecutor {

	private static final Logger log = Logger.getLogger(SimulationExecutor.class);

	private CurrentSimulationStateSingleton currentSimulationState = null;

	private List<SimulationLink> simulationPipeline = new ArrayList<SimulationLink>();

	public SimulationExecutor() {
		currentSimulationState = CurrentSimulationStateSingleton.instance();
	}

	public SimulationExecutor(Collection<SimulationLink> simulationLinks) {
		simulationPipeline.addAll(simulationLinks);
	}

	public void addLink(int index, SimulationLink simulationLink) {
		simulationPipeline.add(index, simulationLink);
	}

	public void addLink(SimulationLink simulationLink) {
		simulationPipeline.add(simulationLink);
	}

	public void runSimulation() {
		if (log.isInfoEnabled()) {
			log.info("Starting simulation...");
		}

		SimulationStateHistorySingleton ssh = SimulationStateHistorySingleton.instance();
		currentSimulationState = CurrentSimulationStateSingleton.instance();

		long startTime = currentSimulationState.getSimulation().getSimulationStart();
		long endTime = currentSimulationState.getSimulation().getSimulationLength();
		long interval = currentSimulationState.getSimulation().getSimulationInterval();

		ssh.getSimulationStateHistory().setEnvironment(currentSimulationState.getEnvironment());
		ssh.getSimulationStateHistory().setSimulation(currentSimulationState.getSimulation());
		ssh.getSimulationStateHistory().setConstantBalloonValues(currentSimulationState.getConstantBalloonValues());

		for (long currentTime = startTime; currentTime <= endTime; currentTime += interval) {
			System.out.println("Running pipeline for " + currentTime + "s...");

			currentSimulationState.getSimulation().setCurrentTime(currentTime);

			for (SimulationLink simulationLink : simulationPipeline) {
				simulationLink.run();
			}

			ssh.add(currentSimulationState.getSimulationState().getExportClone());
		}

		if (log.isInfoEnabled()) {
			log.info("Simulation finished.");
		}
	}
}
